package com.stardata.liangshisq.tcslmon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.stardata.liangshisq.tcslmon.entity.*;
import com.stardata.liangshisq.tcslmon.mapper.ArchPointMapper;
import com.stardata.liangshisq.tcslmon.mapper.BizBsMapper;
import com.stardata.liangshisq.tcslmon.mapper.BizSsMapper;
import com.stardata.liangshisq.tcslmon.mapper.KcKscMapper;
import com.stardata.liangshisq.tcslmon.service.ItemQueueService;
import com.stardata.liangshisq.tcslmon.service.KcKscService;
import com.stardata.liangshisq.tcslmon.service.PrepareService;
import com.stardata.liangshisq.tcslmon.service.SysParameterService;
import com.stardata.liangshisq.tcslmon.util.CommonConstants;
import com.stardata.liangshisq.tcslmon.util.CommonUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Samson Shu
 * @email shush@stardata.top
 * @date 2020/12/14 11:08
 */
@Service
@AllArgsConstructor
public class PrepareServiceImpl implements PrepareService {
  private final Logger logger = LoggerFactory.getLogger(this.getClass());

  private final SimpMessagingTemplate messagingTemplate;
  private final KcKscService kscService;
  private final ItemQueueService itemQueueService;
  private final SysParameterService parameterService;
  private final KcKscMapper kcKscMapper;
  private final BizBsMapper bizBsMapper;
  private final BizSsMapper bizSsMapper;
  private final ArchPointMapper archPointMapper;

  @NotNull
  @Override
  public List<WindowItemVo> queryWindowItems(@NotNull Long shopId, int windowIndex) {
    String windowName = KitchenQueueUtil.getInstance().getPrepareWindowMames().get(windowIndex);
    List<WindowItemVo> result = new ArrayList<>();
    List<WindowItemQueueVo> windowItemQueue = parameterService.getListByCode(windowName, WindowItemQueueVo.class);
    for (WindowItemQueueVo queueVo : windowItemQueue) {
      WindowItemVo itemVo = new WindowItemVo();
      itemVo.setItemId(queueVo.getItemId());
      itemVo.setItemName(queueVo.getItemName());
      itemVo.setIsTempItem(queueVo.getIsTempItem());
      itemVo.setKscIds(queueVo.getKscIds());
      itemVo.setIsJumped(queueVo.getIsJumped());

      itemVo.setCount(queueVo.getKscIds().size());
      itemVo.setTableNames(new ArrayList<>());
      itemVo.setMethods(new ArrayList<>());
      itemVo.setRemarks(new ArrayList<>());
      itemVo.setSourceTypes(new ArrayList<>());
      itemVo.setOrderTimes(new ArrayList<>());

      List<Long> onlineAreaIds = parameterService.getListByCode("onlineAreaIds", Long.class);
      boolean allPrepared = true;
      List<Long> noPreparedId = new ArrayList<>();
      List<Boolean> ksIdsPrepared=new ArrayList<>();
      for (Long kscId : queueVo.getKscIds()) {
        KcKsc kcKsc = kcKscMapper.selectById(kscId);
       if (kcKsc == null) continue;
        if (kcKsc.getKitchenFlg().equals(CommonConstants.KitchenFlg.TO_PREPARE)) {
          allPrepared = false;
          ksIdsPrepared.add(false);
          noPreparedId.add(kscId);
        }else {
        ksIdsPrepared.add(true);
      }
        BizBs bizBs = bizBsMapper.selectById(kcKsc.getBsId());
        if (bizBs == null) continue;

        ArchPoint archPoint = archPointMapper.selectById(bizBs.getPointId());
        if (archPoint == null) continue;

        itemVo.getTableNames().add(archPoint.getName());
        itemVo.getMethods().add(CommonUtil.methodText2List(kcKsc.getMethodText()));

        String remark="";
        QueryWrapper<BizSs> bizSsQueryWrapper = new QueryWrapper<>();
        bizSsQueryWrapper.eq("bs_id", kcKsc.getBsId());
        List<BizSs> bizSsList = bizSsMapper.selectList(bizSsQueryWrapper);
        if (bizSsList.size()>0) {
          remark = bizSsList.get(0).getSsRemark();
        }
        itemVo.getRemarks().add(remark);

        itemVo.getSourceTypes().add(onlineAreaIds.contains(archPoint.getAreaId()) ?
            CommonConstants.OrderSourceType.ONLINE : CommonConstants.OrderSourceType.OFFLINE);
        itemVo.getOrderTimes().add(kcKsc.getCreateTime());
      }
      itemVo.setNoPreparedId(noPreparedId);
      itemVo.setAllPrepared(allPrepared);
      itemVo.setKsIdsPrepared(ksIdsPrepared);
      result.add(itemVo);
    }
    return result;
  }

  @NotNull
  @Override
  public List<ProductVo> queryWaitingItems(@NotNull Long shopId) {
    List<ProductVo> result = new ArrayList<>();
    List<Long> waitingIds = parameterService.getListByCode("itemWaitingList", Long.class);
    if (waitingIds.size()<1) return result;

    QueryWrapper<KcKsc> wrapper = new QueryWrapper<>();
    wrapper.in("id", waitingIds);
    List<KcKsc> kscList = kcKscMapper.selectList(wrapper);
    //这里的排序，确保返回结果仍然是系统保存的排队顺序
    kscList.sort((o1, o2) -> {
      int idx1 = waitingIds.indexOf(o1.getId());
      int idx2 = waitingIds.indexOf(o2.getId());
      return idx1 - idx2;
    });

    List<Long> jumpKscIds = parameterService.getListByCode("jumpItemIds", Long.class);
    for (KcKsc kcKsc : kscList) {
      ProductVo productVo = kscService.convertToProductVo(kcKsc);
      if (productVo != null) {
        result.add(productVo);
        productVo.setIsJumped(jumpKscIds.contains(kcKsc.getId()));
      }
    }
    return result;
  }

  @Override
  public void savePrepareByList(@NotNull Long operUserId, @NotNull List<Long> kcKscIds,
                                @NotNull Boolean prepared) {
    if (prepared) {
      kscService.prepareByList(operUserId, kcKscIds);
    } else {
      kscService.cancelPreparationByList(operUserId, kcKscIds);
    }
    try {
      itemQueueService.refresh();
      messagingTemplate.convertAndSend("/prepare_refresh", "");
      messagingTemplate.convertAndSend("/passon_refresh", "");
    } catch (JsonProcessingException e) {
      logger.error("ERROR===> 刷新配菜中订单的菜品排队，出现JSON格式异常：", e);
    }
  }

  @Override
  public List<ProductVo> queryPrepared(@NotNull Long shopId, String keyword) {
    List<ProductVo> result = kscService.queryCancelableItems(shopId, CommonConstants.KitchenFlg.TO_PASSON, null);
    for (int i = result.size() - 1; i >= 0; i--) {
      ProductVo productVo = result.get(i);
      if (!StringUtils.isBlank(keyword) &&
          !productVo.getItemName().contains(keyword) &&
          !productVo.getTableName().contains(keyword)) {
        result.remove(i);
      }
    }
    return result;
  }
}
